Skip to content

Prepared statements#23156

Draft
trasher wants to merge 1 commit into
glpi-project:mainfrom
trasher:feature/prepared-statements
Draft

Prepared statements#23156
trasher wants to merge 1 commit into
glpi-project:mainfrom
trasher:feature/prepared-statements

Conversation

@trasher
Copy link
Copy Markdown
Contributor

@trasher trasher commented Feb 18, 2026

WIP.

Currently, only "CRUD" related methods have been reworked; as well as DBIterator, and Query* classes.

Since Search engine relies on some f them but also have its own code; it's currently in a non working state. It's the next step; I began to work on this already.
HLAPI tests are also broken; I have no idea how to fix, nor if it's complex or not.

There also is a (minor) problem with 0.85 migration data. seems like the query and parameters are correct regarding sent criteria; and I've not been able to reproduce on my local instance (while I've spotted several other issues on that migration :/)

@trasher trasher force-pushed the feature/prepared-statements branch 4 times, most recently from b9fbbae to 22f869e Compare February 24, 2026 09:07
@cedric-anne cedric-anne added this to the 12.0.0 milestone Mar 2, 2026
@trasher trasher force-pushed the feature/prepared-statements branch 2 times, most recently from 688c58b to 2b65826 Compare March 5, 2026 13:11
@trasher trasher force-pushed the feature/prepared-statements branch 9 times, most recently from 95c0aed to 9b9c0cd Compare March 12, 2026 10:08
Comment thread src/DBmysql.php Outdated
Comment thread tests/functional/MigrationTest.php Outdated
Comment thread tests/functional/MigrationTest.php Outdated
@trasher trasher force-pushed the feature/prepared-statements branch 2 times, most recently from f833f2f to 6c98d07 Compare March 16, 2026 14:26
@trasher trasher force-pushed the feature/prepared-statements branch 2 times, most recently from 374aae7 to 9117f26 Compare April 7, 2026 08:23
@trasher trasher force-pushed the feature/prepared-statements branch from 9117f26 to 5f730a1 Compare April 13, 2026 08:39
Copy link
Copy Markdown
Member

@cedric-anne cedric-anne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proposed way to migrate to prepared queries is globally OK for me.

Comment thread src/Glpi/Dashboard/Provider.php
Comment thread src/Glpi/DBAL/Delete.php Outdated
* @param string $expression The query expression
* @param ?string $alias The query expression alias
*/
public function __construct($expression, ?string $alias = null)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may help to produce less verbose code, for instance new QueryExpression('IF(field, ?, ?)', values: ['foo', 'bar'], alias: 'whatever').

Suggested change
public function __construct($expression, ?string $alias = null, array $values = [])

};
$func_name = strtoupper($func_name);
return self::getExpression($func_name, $params, $args[1] ?? null);
//FIXME: no idea how to handle possible statement values, and even if there are some...
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should not try to handle them. I even think we should deprecate this magic method, and declare simple static methods that corresponds to used functions. Anyway, it is out of the scope of this PR.

Comment thread src/Glpi/DBAL/QueryFunction.php Outdated
Comment thread install/migrations/update_9.4.3_to_9.4.5.php Outdated
Comment thread src/Glpi/Console/Diagnostic/CheckHtmlEncodingCommand.php Outdated
Comment thread src/Migration.php
]
);
} catch (StatementException $e) {
if (!str_contains($e->getMessage(), 'Duplicate entry')) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A Duplicate entry is unexpected here, since dusplicates are supposed to be cleaned on lines 1100-1102.


$this->expectExceptionMessage(
'`Computer::getFromDBByRequest()` expects to get one result, 2 found in query "SELECT `glpi_computers`.* FROM `glpi_computers` WHERE `contact` = \'johndoe\'".'
'`Computer::getFromDBByRequest()` expects to get one result, 2 found in query "SELECT `glpi_computers`.* FROM `glpi_computers` WHERE `contact` = ?".'
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to preserve values in the exception message ?


namespace Glpi\DBAL;

abstract class Prepared
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the names of the new classes could be more precise. For instance AbstractPreparedQuery, DeletePreparedQuery, ...

Rework affected rows (must be retrieved from statement)
Handle Prepared from migrations
Handle possible exisiting QueryExpression statement values
Try to detect early bind issues

Limit to simple cases for now
Fix prepared IN, fix buildUpdate
Try to get extra information on failure

rawAnalyzeCrit (maybe to remove)
@trasher trasher force-pushed the feature/prepared-statements branch from 87349ba to f84f3c7 Compare May 13, 2026 08:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants